import os
import re
from typing import List

from ninja import Router, UploadedFile, File, Form
from ninja.pagination import paginate
from django.contrib.auth.hashers import make_password, check_password
from django.core.cache import cache

from apps.commom.user import RegionInfoSerializer
from apps.manager.user_manager.schemas import ManagerUserCreateSchema, ManagerUserLoginSchema, \
    ManagerUserChangePasswordSchema, ManagerUsersResponseSchema, UploadFileSchema
from apps.manager.user_manager.serializers import ManagerUserSerializer
from apps.schemas import R
from models.models import ManagerUser, RegionInfo
from utils.auth import ManagerAuthBearer
from utils.decorators import handle_exception
from utils.encryption import cal_sha1_string, make_token
from utils.paginations import MyPagination
from utils.snowflake import snowflake
from water_applets import settings

manager_user_router = Router(tags=['后台用户管理'])


@manager_user_router.get("/manager_users", summary="获取用户列表", auth=ManagerAuthBearer(),
                         response=List[ManagerUsersResponseSchema])
@paginate(MyPagination)
@handle_exception("获取用户列表失败")
def get_manager_users(request):
    users = ManagerUser.objects.all().order_by("create_time")
    return users


@manager_user_router.get("/manager_user/info/{user_id}", summary="获取用户信息", auth=ManagerAuthBearer())
@handle_exception("获取用户信息失败")
def get_manager_user(request, user_id):
    user = ManagerUser.objects.get(id=user_id)
    return R.ok(ManagerUserSerializer(user).data)


@manager_user_router.post("/manager_user", summary="创建用户", auth=ManagerAuthBearer())
@handle_exception("创建用户失败")
def create_manager_user(request, data: ManagerUserCreateSchema):
    email_re = re.compile(r'^\w+@(\w+\.)+(com|cn|net|edu)$')
    number_re = re.compile(r'^1[3-9]\d{9}$')
    if not email_re.search(data.email):
        return R.fail("邮箱格式错误")
    elif not number_re.search(data.mobile):
        return R.fail("手机号格式错误")
    if ManagerUser.objects.filter(username=data.username).exists():
        return R.fail("该用户已存在")
    else:
        pw = make_password(cal_sha1_string(data.password))
        data_dict = data.dict()
        data_dict.update({"password": pw})
        ManagerUser.objects.create(**data_dict)
    return R.ok(msg="创建成功")


@manager_user_router.post("/manager_user/change_pw", summary="修改用户密码", auth=ManagerAuthBearer(),
                          openapi_extra={"user_default": True})
@handle_exception("修改用户密码失败")
def change_manager_user_pw(request, data: ManagerUserChangePasswordSchema):
    password = cal_sha1_string(data.old_password)
    if not check_password(password, request.user.password):
        return R.fail("原密码错误")
    request.user.password = make_password(cal_sha1_string(data.new_password))
    request.user.save()
    return R.ok(msg="修改成功")


@manager_user_router.get("/manager_user/logout", summary="管理用户登出", auth=ManagerAuthBearer(),
                         openapi_extra={"user_default": True})
@handle_exception("管理用户登出失败")
def manager_user_logout(request):
    login_token_key = settings.REDIS_MANAGER_LOGIN_TOKEN_KEY.format(user_id=request.user.id)
    cache.delete(login_token_key)
    user = request.user
    user.on_line = False
    user.save()
    return R.ok(msg="退出成功")


@manager_user_router.post("/manager_user/login", summary="管理用户登录", openapi_extra={"user_default": True})
@handle_exception("管理用户登录失败")
def manager_user_login(request, data: ManagerUserLoginSchema):
    if not ManagerUser.objects.filter(username=data.username).exists():
        return R.fail("用户不存在")
    user = ManagerUser.objects.get(username=data.username)
    pw = cal_sha1_string(data.password)
    if not check_password(pw, user.password):
        return R.fail("密码错误")
    token = make_token()
    login_token_key = settings.REDIS_MANAGER_LOGIN_TOKEN_KEY.format(user_id=user.id)
    cache.set(login_token_key, token, timeout=settings.MANAGER_LOGIN_TOKEN_EXPIRE)
    user.on_line = True
    user.save()
    return R.ok({"token": token, "user": ManagerUserSerializer(user).data})


@manager_user_router.post("/file/upload", summary="上传文件", auth=ManagerAuthBearer())
@handle_exception("上传文件失败")
def upload_picture(request, data: Form[UploadFileSchema],  file: UploadedFile = File(...)):
    folder = f"static/{data.type}"
    prefix, suffix = os.path.splitext(file.name)
    save_path = f"{folder}/{prefix}-{snowflake()}{suffix}"
    if not os.path.exists(folder):
        os.makedirs(folder)
    with open(save_path, "wb") as f:
        f.write(file.read())
    return R.ok(save_path)


@manager_user_router.get("/region_infos", summary="获取区域信息")
@handle_exception("获取区域信息失败")
def get_region_infos(request):
    """
    获取区域信息
    """
    region_infos = RegionInfo.objects.filter(parent_id=0)
    return R.ok(data=RegionInfoSerializer(region_infos, many=True).data)


@manager_user_router.get("/region_info/{pid}", summary="查询下属区域信息")
@handle_exception("查询下属区域信息")
def get_region_infos(request, pid: int):
    """
    获取区域信息
    """
    region_infos = RegionInfo.objects.filter(parent_id=pid)
    return R.ok(data=RegionInfoSerializer(region_infos, many=True).data)